unit Dinput;

interface

uses
  DirectInput,
  Sysutils,
  Windows,
  Debug,
  Engine;

type

  TInput = class
    DInput: IDirectInput8;
    DInputKey: IDirectInputDevice8;
    DInputMouse: IDirectInputDevice8;
    Key_State: array[0..255] of byte;
    WMODE: Boolean;
    Mouse_State: DIMouseState;
    MouseX, MouseY: integer;
    Mouse_L, Mouse_R: boolean;
    Screen_W, Screen_H: integer;
    function Initial(GWindow: HWND; W_Mode: Boolean): integer;
    procedure Release;
    function GetKeyState: integer;
  end;

  PInput = ^TInput;

implementation

function TInput.Initial(GWindow: HWND; W_Mode: Boolean): integer;
var
  Mpos: Tpoint;
begin
  WMODE := W_Mode;
  Screen_W := GetSystemMetrics(SM_CXSCREEN);
  Screen_H := GetSystemMetrics(SM_CYSCREEN);

  GameDebug.AddDebugInfo('Cteate DirectInput!');
  if DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, DInput, nil) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Cteate DirectInput Fail!');
    result := 2;
    exit;
  end;

  GameDebug.AddDebugInfo('Cteate DirectInput Keyboard!');
  if Dinput.CreateDevice(GUID_SysKeyboard, DinputKey, nil) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Cteate DirectInput Keyboard Fail!');
    result := 3;
    exit;
  end;

  GameDebug.AddDebugInfo('Set DirectInput Keyboard Cooperative Level!');
  if DinputKey.SetCooperativeLevel(Gwindow, DISCL_NONEXCLUSIVE or DISCL_BACKGROUND) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Set DirectInput Keyboard Cooperative Level Fail!');
    result := 4;
    exit;
  end;

  GameDebug.AddDebugInfo('Set DirectInput Keyboard Data Format!');
  if DinputKey.SetDataFormat(c_dfDIKeyboard) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Set DirectInput Keyboard Data Format Fail!');
    result := 5;
    exit;
  end;

  GameDebug.AddDebugInfo('DirectInput Keyboard Acquire!');
  if DinputKey.Acquire <> DI_OK then
  begin
    GameDebug.AddDebugInfo('DirectInput Keyboard Acquire Fail!');
    result := 6;
    exit;
  end;

  GameDebug.AddDebugInfo('Cteate DirectInput Mouse!');
  if Dinput.CreateDevice(GUID_SysMouse, DinputMouse, nil) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Cteate DirectInput Mouse Fail!');
    result := 7;
    exit;
  end;

  GameDebug.AddDebugInfo('Set DirectInput Mouse Cooperative Level!');
  if DinputMouse.SetCooperativeLevel(Gwindow, DISCL_BACKGROUND or DISCL_NONEXCLUSIVE{DISCL_NONEXCLUSIVE or DISCL_BACKGROUND}) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Set DirectInput Mouse Cooperative Level Fail!');
    result := 8;
    exit;
  end;

  GameDebug.AddDebugInfo('Set DirectInput Mouse Data Format!');
  if DinputMouse.SetDataFormat(c_dfDIMouse) <> DI_OK then
  begin
    GameDebug.AddDebugInfo('Set DirectInput Mouse Data Format Fail!');
    result := 9;
    exit;
  end;

  GameDebug.AddDebugInfo('DirectInput Mouse Acquire!');
  if DinputMouse.Acquire <> DI_OK then
  begin
    GameDebug.AddDebugInfo('DirectInput Mouse Acquire Fail!');
    result := 10;
    exit;
  end;
  GetCursorpos(Mpos);
  MouseX := Mpos.X;
  MouseY := Mpos.Y;

  result := 0;
end;

function TInput.GetKeyState: integer;
var
  Mpos: TPoint;
begin
  DinputKey.GetDeviceState(256, @Key_State[0]);
  Mouse_L := false;
  Mouse_R := false;

  if DinputMouse.GetDevicestate(sizeof(DIMOUSESTATE), @mouse_state) = DI_OK then
  //if DinputMouse.GetDevicedata() = DI_OK then
  begin
    MouseX := MouseX + Mouse_State.lX;
    if MouseX < 0 then
      MouseX := 0
    else if MouseX >= Screen_W then
      MouseX :=Screen_W - 1;
    MouseY := MouseY + Mouse_State.lY;
    if MouseY < 0 then
      MouseY := 0
    else if MouseY >= Screen_H then
      MouseY := Screen_H - 1;
  end;

  if WMODE then
  begin
    GetCursorpos(Mpos);
    MouseX := Mpos.X;
    MouseY := Mpos.Y;
  end;
  //if WMode then
    //SetCursorpos(MouseX, MouseY);
end;

procedure TInput.Release;
begin
  GameDebug.AddDebugInfo('Release DirectInput!');
  DinputKey.Unacquire;
  Dinputkey._Release;
  DinputMouse.Unacquire;
  DinputMouse._Release;
end;

end.
